#include "stdafx.h"
#include <windows.h>
#include "OpenGL.h"
#include <iostream>
#include "Header.h"
#include "Text.h"
#include <math.h>
#include <vector>
#include <tuple>
#include <gl\gl.h>
#include <gl\GLU.h>
#include <psapi.h>
#include <stdio.h>
#include <fstream>
#define EPSILON 0.1
#define FLOAT_EQ(x,v) (((v - EPSILON) < x) && (x <( v + EPSILON)))
#define FIRST_TIMER 100
#pragma comment(lib, "dll_export.lib")
using namespace std;

HDC hDC;
HWND child;
HWND hWND;
HGLRC hGLRC;
double h;
vector<int> choise;
vector<int> pointscenter;
#define MAX_LOADSTRING 100

// Global Variables:
HINSTANCE hInst;                                // current instance
WCHAR szTitle[MAX_LOADSTRING];                  // The title bar text
WCHAR szWindowClass[MAX_LOADSTRING];            // the main window class name

// Forward declarations of functions included in this code module:
ATOM                MyRegisterClass(HINSTANCE hInstance);
BOOL                InitInstance(HINSTANCE, int);
LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK    About(HWND, UINT, WPARAM, LPARAM);

int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
	_In_opt_ HINSTANCE hPrevInstance,
	_In_ LPWSTR    lpCmdLine,
	_In_ int       nCmdShow)
{
	UNREFERENCED_PARAMETER(hPrevInstance);
	UNREFERENCED_PARAMETER(lpCmdLine);

	// TODO: Place code here.

	// Initialize global strings
	LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
	LoadStringW(hInstance, IDC_OPENGL, szWindowClass, MAX_LOADSTRING);
	MyRegisterClass(hInstance);

	// Perform application initialization:
	if (!InitInstance(hInstance, nCmdShow))
	{
		return FALSE;
	}
	HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_OPENGL));

	MSG msg;

	// Main message loop:
	while (GetMessage(&msg, nullptr, 0, 0))
	{
		if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
	}

	return (int)msg.wParam;
}

//
//  FUNCTION: MyRegisterClass()
//
//  PURPOSE: Registers the window class.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
	WNDCLASSEXW wcex = { 0 };

	wcex.cbSize = sizeof(WNDCLASSEX);

	wcex.style = CS_HREDRAW | CS_VREDRAW;
	wcex.lpfnWndProc = WndProc;
	wcex.cbClsExtra = 0;
	wcex.cbWndExtra = 0;
	wcex.hInstance = hInstance;
	wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_OPENGL));
	wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
	wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
	wcex.lpszMenuName = MAKEINTRESOURCEW(IDC_OPENGL);
	wcex.lpszClassName = szWindowClass;
	wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

	return RegisterClassExW(&wcex);
}

//
//   FUNCTION: InitInstance(HINSTANCE, int)
//
//   PURPOSE: Saves instance handle and creates main window
//
//   COMMENTS:
//
//        In this function, we save the instance handle in a global variable and
//        create and display the main program window.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
	hInst = hInstance; // Store instance handle in our global variable
	hWND = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
		0, 0, 800, 800, nullptr, nullptr, hInst, nullptr);

	if (!hWND)
	{
		return FALSE;
	}

	ShowWindow(hWND, nCmdShow);

	UpdateWindow(hWND);
	SetFocus(hWND);
	return TRUE;
}

void resize(int width, int height)
{
	/*glMatrixMode(GL_PROJECTION);*/
	glLoadIdentity();
	float left = 0;
	float right = width;
	float bottom = 0;
	float 	top = height;
	h = height;
	glOrtho(left, right, bottom, top, 0, 1);
	/*glMatrixMode(GL_MODELVIEW);*/
	glViewport(0, 0, width, height);
}

//
//  FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
//
//  PURPOSE:  Processes messages for the main window.
//
//  WM_COMMAND  - process the application menu
//  WM_PAINT    - Paint the main window
//  WM_DESTROY  - post a quit message and return
//
//

Make_Figure *myfigure = new Make_Figure();
vector<float> color;
BOOL CALLBACK DlgProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK WndProc(HWND hWND, UINT message, WPARAM wParam, LPARAM lParam)
{
	HDC     glhdc;
	HBITMAP oldbmp;
	PAINTSTRUCT ps;

	switch (message)
	{
	case WM_CREATE:
	{
		hDC = GetDC(hWND);
		glhdc = CreateCompatibleDC(hDC);
		oldbmp = (HBITMAP)SelectObject(glhdc, CreateCompatibleBitmap(hDC, 100, 100));
		ReleaseDC(hWND, hDC);
		PIXELFORMATDESCRIPTOR pfd;

		pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
		pfd.nVersion = 1;

		pfd.dwFlags = PFD_DRAW_TO_WINDOW |
			PFD_SUPPORT_OPENGL |
			PFD_DOUBLEBUFFER;

		pfd.iPixelType = PFD_TYPE_RGBA;
		pfd.cColorBits = 32;
		pfd.cRedBits = 8;
		pfd.cRedShift = 16;
		pfd.cGreenBits = 8;
		pfd.cGreenShift = 8;
		pfd.cBlueBits = 8;
		pfd.cBlueShift = 0;
		pfd.cAlphaBits = 0;
		pfd.cAlphaShift = 0;
		pfd.cAccumBits = 64;
		pfd.cAccumRedBits = 16;
		pfd.cAccumGreenBits = 16;
		pfd.cAccumBlueBits = 16;
		pfd.cAccumAlphaBits = 0;
		pfd.cDepthBits = 32;
		pfd.cStencilBits = 8;
		pfd.cAuxBuffers = 0;
		pfd.iLayerType = PFD_MAIN_PLANE;
		pfd.bReserved = 0;
		pfd.dwLayerMask = 0;
		pfd.dwVisibleMask = 0;
		pfd.dwDamageMask = 0;
		int m_GLPixelIndex = ChoosePixelFormat(hDC, &pfd);
		hDC = GetDC(hWND);
		//	SetTimer(hWND, WM_MOUSEWHEEL, 1, 0);
		int pixelFormat = ChoosePixelFormat(hDC, &pfd);

		SetPixelFormat(hDC, pixelFormat, &pfd);

		hGLRC = wglCreateContext(hDC);

		wglMakeCurrent(hDC, hGLRC);
		break;
	}
	case WM_TIMER:
		if (wParam == FIRST_TIMER)
		{
			break;
		}
	case WM_MOUSEWHEEL:
	{
		int wheelDelta = GET_WHEEL_DELTA_WPARAM(wParam);
		double l = 0;
		if (wheelDelta > 0)
		{
			l += 3.1416 / 500;
		}
		else
		{
			l -= 3.1416 / 500;
		}
		POINT pt;

		GetCursorPos(&pt);

		ScreenToClient(hWND, &pt);
		pt.y = h - pt.y;

		auto figures = myfigure->getFigures();
		if (!choise.empty())
		{
			auto iter = figures.begin();
			for (int i = 0;i < choise.size();i++)
			{
				iter += choise[i];
				vector<double> coord = (*iter)->get_list_coordinates();
				if ((*iter)->figure() == "Triangle")
				{
					vector<double> coordTr = (*iter)->get_list_coordinates();
					double x[3]; double y[3];

					vector<double> xx, yy;
					xx.resize(3);
					yy.resize(3);
					x[0] = coordTr[0];
					x[1] = coordTr[2];
					x[2] = coordTr[4];
					y[0] = coordTr[1];
					y[1] = coordTr[3];
					y[2] = coordTr[5];
					double divy = (y[0] + y[1] + y[2]) / 3;
					double divx = (x[0] + x[1] + x[2]) / 3;
					xx[0] = (divx + ((x[0] - divx) * cos((l)) - (y[0] - divy) * sin(l)));
					yy[0] = (divy + ((y[0] - divy) * cos((l)) + (x[0] - divx) * sin(l)));

					xx[1] = (divx + ((x[1] - divx) * cos(l) - (y[1] - divy) * sin(l)));
					yy[1] = (divy + ((y[1] - divy) * cos(l) + (x[1] - divx) * sin(l)));

					xx[2] = (divx + ((x[2] - divx) * cos(l) - (y[2] - divy) * sin(l)));
					yy[2] = (divy + ((y[2] - divy) * cos(l) + (x[2] - divx) * sin(l)));

					(*iter)->set(xx, yy);
				}
				if ((*iter)->figure() == "Circle")
				{
					vector<double> coordCr = (*iter)->get_list_coordinates();
					vector<double> xx, yy;
					xx.resize(600);
					yy.resize(600);
					double Rx = coordCr.at(0);
					double Ry = coordCr.at(1);
					for (int i = 0, z = 0;i < 1200;i += 2)
					{
						xx[z] = Rx + ((coordCr[i] - Rx) * cos((l)) - (coordCr[i + 1] - Ry) * sin(l));
						yy[z] = Ry + ((coordCr[i + 1] - Ry) * cos((l)) + (coordCr[i] - Rx) * sin(l));
						z++;
					}

					(*iter)->set(xx, yy);
				}
				if ((*iter)->figure() == "Rectangle")
				{
					vector<double> coordRe = (*iter)->get_list_coordinates();
					vector<double> xx, yy;
					xx.resize(4);
					yy.resize(4);
					double divy = (coordRe[1] + coordRe[3] + coordRe[5] + coordRe[7]) / 4;
					double divx = (coordRe[0] + coordRe[2] + coordRe[4] + coordRe[6]) / 4;
					xx[0] = divx + ((coordRe[0] - divx) * cos((l)) - (coordRe[1] - divy) * sin(l));
					yy[0] = divy + ((coordRe[1] - divy) * cos((l)) + (coordRe[0] - divx) * sin(l));

					xx[1] = divx + ((coordRe[2] - divx) * cos(l) - (coordRe[3] - divy) * sin(l));
					yy[1] = divy + ((coordRe[3] - divy) * cos(l) + (coordRe[2] - divx) * sin(l));

					xx[2] = (divx + ((coordRe[4] - divx) * cos(l) - (coordRe[5] - divy) * sin(l)));
					yy[2] = (divy + ((coordRe[5] - divy) * cos(l) + (coordRe[4] - divx) * sin(l)));

					xx[3] = (divx + ((coordRe[6] - divx) * cos(l) - (coordRe[7] - divy) * sin(l)));
					yy[3] = (divy + ((coordRe[7] - divy) * cos(l) + (coordRe[6] - divx) * sin(l)));

					(*iter)->set(xx, yy);
				}
				iter -= choise[i];
			}
		}
		for (auto iter = figures.begin(); iter != figures.end(); iter++)
		{
			if ((*iter)->figure() == "Triangle")
			{
				vector<double> coordTr = (*iter)->get_list_coordinates();

				float length_1_x = abs(coordTr.at(0) - pt.x);
				float length_2_x = abs(coordTr[2] - pt.x);
				float length_3_x = abs(coordTr.at(4) - pt.x);

				float length_1_y = abs(coordTr.at(1) - pt.y);
				float length_2_y = abs(coordTr.at(3) - pt.y);
				float length_3_y = abs(coordTr.at(5) - pt.y);

				float length_1_tr = sqrt(length_1_y*length_1_y + length_1_x*length_1_x);
				float length_2_tr = sqrt(length_2_x*length_2_x + length_2_y*length_2_y);
				float length_3_tr = sqrt(length_3_y*length_3_y + length_3_x*length_3_x);

				float length_1_x_Tr = abs(coordTr.at(0) - coordTr.at(2));
				float length_2_x_Tr = abs(coordTr.at(0) - coordTr.at(4));
				float length_3_x_Tr = abs(coordTr.at(2) - coordTr.at(4));

				float length_1_y_Tr = abs(coordTr.at(1) - coordTr.at(3));
				float length_2_y_Tr = abs(coordTr.at(1) - coordTr.at(5));
				float length_3_y_Tr = abs(coordTr.at(3) - coordTr.at(5));

				float length_1 = sqrt(length_1_y_Tr*length_1_y_Tr + length_1_x_Tr*length_1_x_Tr);
				float length_2 = sqrt(length_2_x_Tr*length_2_x_Tr + length_2_y_Tr*length_2_y_Tr);
				float length_3 = sqrt(length_3_y_Tr*length_3_y_Tr + length_3_x_Tr*length_3_x_Tr);

				float p_05_1_Tr = (length_1 + length_2 + length_3) / 2;
				float p_05_1_tr = (length_1 + length_2_tr + length_1_tr) / 2;
				float p_05_2_tr = (length_2 + length_1_tr + length_3_tr) / 2;
				float p_05_3_tr = (length_3 + length_3_tr + length_2_tr) / 2;

				float S_Tr = sqrt(p_05_1_Tr*(p_05_1_Tr - length_1)*(p_05_1_Tr - length_2)*(p_05_1_Tr - length_3));
				float S_1_tr = sqrt(p_05_1_tr*(p_05_1_tr - length_1)*(p_05_1_tr - length_2_tr)*(p_05_1_tr - length_1_tr));
				float S_2_tr = sqrt(p_05_2_tr*(p_05_2_tr - length_2)*(p_05_2_tr - length_1_tr)*(p_05_2_tr - length_3_tr));
				float S_3_tr = sqrt(p_05_3_tr*(p_05_3_tr - length_3)*(p_05_3_tr - length_3_tr)*(p_05_3_tr - length_2_tr));

				float sum = S_1_tr + S_2_tr + S_3_tr;
				if (FLOAT_EQ(S_Tr, sum))
				{
					double x[3]; double y[3];

					vector<double> xx, yy;
					xx.resize(3);
					yy.resize(3);
					x[0] = coordTr[0];
					x[1] = coordTr[2];
					x[2] = coordTr[4];
					y[0] = coordTr[1];
					y[1] = coordTr[3];
					y[2] = coordTr[5];
					double divy = (y[0] + y[1] + y[2]) / 3;
					double divx = (x[0] + x[1] + x[2]) / 3;
					xx[0] = (divx + ((x[0] - divx) * cos((l)) - (y[0] - divy) * sin(l)));
					yy[0] = (divy + ((y[0] - divy) * cos((l)) + (x[0] - divx) * sin(l)));

					xx[1] = (divx + ((x[1] - divx) * cos(l) - (y[1] - divy) * sin(l)));
					yy[1] = (divy + ((y[1] - divy) * cos(l) + (x[1] - divx) * sin(l)));

					xx[2] = (divx + ((x[2] - divx) * cos(l) - (y[2] - divy) * sin(l)));
					yy[2] = (divy + ((y[2] - divy) * cos(l) + (x[2] - divx) * sin(l)));

					(*iter)->set(xx, yy);
					break;
				}
			}
			if ((*iter)->figure() == "Circle")
			{
				vector<double> coordCr = (*iter)->get_list_coordinates();
				if ((30)*(30) > (pt.x - coordCr.at(0))*(pt.x - coordCr.at(0)) + (pt.y - coordCr.at(1))*(pt.y - coordCr.at(1)))
				{
					vector<double> xx, yy;
					xx.resize(600);
					yy.resize(600);
					double Rx = coordCr.at(0);
					double Ry = coordCr.at(1);
					for (int i = 0, z = 0;i < 1200;i += 2)
					{
						xx[z] = Rx + ((coordCr[i] - Rx) * cos((l)) - (coordCr[i + 1] - Ry) * sin(l));
						yy[z] = Ry + ((coordCr[i + 1] - Ry) * cos((l)) + (coordCr[i] - Rx) * sin(l));
						z++;
					}

					(*iter)->set(xx, yy);
					break;
				}
			}
			if ((*iter)->figure() == "Rectangle")
			{
				vector<double> coordRe = (*iter)->get_list_coordinates();

				float length_1_x = abs(coordRe.at(0) - pt.x);
				float length_2_x = abs(coordRe.at(2) - pt.x);
				float length_3_x = abs(coordRe.at(4) - pt.x);
				float length_4_x = abs(coordRe.at(6) - pt.x);

				float length_1_y = abs(coordRe.at(1) - pt.y);
				float length_2_y = abs(coordRe.at(3) - pt.y);
				float length_3_y = abs(coordRe.at(5) - pt.y);
				float length_4_y = abs(coordRe.at(7) - pt.y);

				float length_1_tr = sqrt(length_1_y*length_1_y + length_1_x*length_1_x);
				float length_2_tr = sqrt(length_2_x*length_2_x + length_2_y*length_2_y);
				float length_3_tr = sqrt(length_3_y*length_3_y + length_3_x*length_3_x);
				float length_4_tr = sqrt(length_4_y*length_4_y + length_4_x*length_4_x);

				float length_1_x_Re = abs(coordRe.at(0) - coordRe.at(2));
				float length_2_x_Re = abs(coordRe.at(0) - coordRe.at(4));
				float length_3_x_Re = abs(coordRe.at(2) - coordRe.at(6));
				float length_4_x_Re = abs(coordRe.at(4) - coordRe.at(6));

				float length_1_y_Re = abs(coordRe.at(1) - coordRe.at(3));
				float length_2_y_Re = abs(coordRe.at(1) - coordRe.at(5));
				float length_3_y_Re = abs(coordRe.at(3) - coordRe.at(7));
				float length_4_y_Re = abs(coordRe.at(5) - coordRe.at(7));

				float length_1 = sqrt(length_1_y_Re*length_1_y_Re + length_1_x_Re*length_1_x_Re);
				float length_2 = sqrt(length_2_x_Re*length_2_x_Re + length_2_y_Re*length_2_y_Re);
				float length_3 = sqrt(length_3_y_Re*length_3_y_Re + length_3_x_Re*length_3_x_Re);
				float length_4 = sqrt(length_4_y_Re*length_4_y_Re + length_4_x_Re*length_4_x_Re);

				float p_05_1_tr = (length_1 + length_2_tr + length_1_tr) / 2;
				float p_05_2_tr = (length_2 + length_1_tr + length_3_tr) / 2;
				float p_05_3_tr = (length_3 + length_4_tr + length_2_tr) / 2;
				float p_05_4_tr = (length_4 + length_4_tr + length_3_tr) / 2;

				float S_Re = length_1*length_2;
				float S_1_tr = sqrt(p_05_1_tr*(p_05_1_tr - length_1)*(p_05_1_tr - length_2_tr)*(p_05_1_tr - length_1_tr));
				float S_2_tr = sqrt(p_05_2_tr*(p_05_2_tr - length_2)*(p_05_2_tr - length_1_tr)*(p_05_2_tr - length_3_tr));
				float S_3_tr = sqrt(p_05_3_tr*(p_05_3_tr - length_3)*(p_05_3_tr - length_4_tr)*(p_05_3_tr - length_2_tr));
				float S_4_tr = sqrt(p_05_4_tr*(p_05_4_tr - length_4)*(p_05_4_tr - length_4_tr)*(p_05_4_tr - length_3_tr));

				float sum = S_1_tr + S_2_tr + S_3_tr + S_4_tr;

				if (FLOAT_EQ(S_Re, sum))
				{
					vector<double> xx, yy;
					xx.resize(4);
					yy.resize(4);
					double divy = (coordRe[1] + coordRe[3] + coordRe[5] + coordRe[7]) / 4;
					double divx = (coordRe[0] + coordRe[2] + coordRe[4] + coordRe[6]) / 4;
					xx[0] = divx + ((coordRe[0] - divx) * cos((l)) - (coordRe[1] - divy) * sin(l));
					yy[0] = divy + ((coordRe[1] - divy) * cos((l)) + (coordRe[0] - divx) * sin(l));

					xx[1] = divx + ((coordRe[2] - divx) * cos(l) - (coordRe[3] - divy) * sin(l));
					yy[1] = divy + ((coordRe[3] - divy) * cos(l) + (coordRe[2] - divx) * sin(l));

					xx[2] = (divx + ((coordRe[4] - divx) * cos(l) - (coordRe[5] - divy) * sin(l)));
					yy[2] = (divy + ((coordRe[5] - divy) * cos(l) + (coordRe[4] - divx) * sin(l)));

					xx[3] = (divx + ((coordRe[6] - divx) * cos(l) - (coordRe[7] - divy) * sin(l)));
					yy[3] = (divy + ((coordRe[7] - divy) * cos(l) + (coordRe[6] - divx) * sin(l)));

					(*iter)->set(xx, yy);
					break;
				}
			}
		}

		InvalidateRect(hWND, NULL, TRUE);
		break;
	}
	case WM_MBUTTONDOWN:
	{
		POINT pt;

		GetCursorPos(&pt);

		ScreenToClient(hWND, &pt);

		pt.y = h - pt.y;
		Figure *x_figure;

		vector<double> x_number, y_number;

		x_number.push_back(pt.x + 30);

		y_number.push_back(pt.y + 30);
		x_number.push_back(pt.x + 30);

		y_number.push_back(pt.y - 30);
		x_number.push_back(pt.x - 30);

		y_number.push_back(pt.y + 30);
		x_number.push_back(pt.x - 30);

		y_number.push_back(pt.y - 30);
		x_figure = new rectangle(x_number, y_number);

		myfigure->push_back(x_figure);

		InvalidateRect(hWND, NULL, TRUE);

		break;
	}
	case WM_RBUTTONDOWN:
	{
		POINT pt;

		GetCursorPos(&pt);

		ScreenToClient(hWND, &pt);

		pt.y = h - pt.y;
		Figure *x_figure;

		std::vector<double> x;
		std::vector<double> y;
		x.resize(600);
		y.resize(600);
		for (int i = 0;i < 600;i++)
		{
			if (i == 0)
			{
				x[i] = pt.x;
				y[i] = pt.y;
			}
			else
			{
				float angle = 2.0 * 3.1415926 * float(i) / float(600);
				x[i] = pt.x + 30 * cos(angle);
				y[i] = pt.y + 30 * sin(angle);
			}
		}
		x_figure = new circle(x, y);
		myfigure->push_back(x_figure);

		InvalidateRect(hWND, NULL, TRUE);

		break;
	}

	case WM_LBUTTONDOWN:
	{
		if (GetAsyncKeyState(VK_CONTROL))
		{
			POINT pt;

			GetCursorPos(&pt);

			ScreenToClient(hWND, &pt);
			pt.y = h - pt.y;

			auto figures = myfigure->getFigures();
			int k = 0;
			for (auto iter = figures.begin(); iter != figures.end(); iter++, k++)
			{
				if ((*iter)->figure() == "Triangle")
				{
					vector<double> coordTr = (*iter)->get_list_coordinates();

					float length_1_x = abs(coordTr.at(0) - pt.x);
					float length_2_x = abs(coordTr[2] - pt.x);
					float length_3_x = abs(coordTr.at(4) - pt.x);

					float length_1_y = abs(coordTr.at(1) - pt.y);
					float length_2_y = abs(coordTr.at(3) - pt.y);
					float length_3_y = abs(coordTr.at(5) - pt.y);

					float length_1_tr = sqrt(length_1_y*length_1_y + length_1_x*length_1_x);
					float length_2_tr = sqrt(length_2_x*length_2_x + length_2_y*length_2_y);
					float length_3_tr = sqrt(length_3_y*length_3_y + length_3_x*length_3_x);

					float length_1_x_Tr = abs(coordTr.at(0) - coordTr.at(2));
					float length_2_x_Tr = abs(coordTr.at(0) - coordTr.at(4));
					float length_3_x_Tr = abs(coordTr.at(2) - coordTr.at(4));

					float length_1_y_Tr = abs(coordTr.at(1) - coordTr.at(3));
					float length_2_y_Tr = abs(coordTr.at(1) - coordTr.at(5));
					float length_3_y_Tr = abs(coordTr.at(3) - coordTr.at(5));

					float length_1 = sqrt(length_1_y_Tr*length_1_y_Tr + length_1_x_Tr*length_1_x_Tr);
					float length_2 = sqrt(length_2_x_Tr*length_2_x_Tr + length_2_y_Tr*length_2_y_Tr);
					float length_3 = sqrt(length_3_y_Tr*length_3_y_Tr + length_3_x_Tr*length_3_x_Tr);

					float p_05_1_Tr = (length_1 + length_2 + length_3) / 2;
					float p_05_1_tr = (length_1 + length_2_tr + length_1_tr) / 2;
					float p_05_2_tr = (length_2 + length_1_tr + length_3_tr) / 2;
					float p_05_3_tr = (length_3 + length_3_tr + length_2_tr) / 2;

					float S_Tr = sqrt(p_05_1_Tr*(p_05_1_Tr - length_1)*(p_05_1_Tr - length_2)*(p_05_1_Tr - length_3));
					float S_1_tr = sqrt(p_05_1_tr*(p_05_1_tr - length_1)*(p_05_1_tr - length_2_tr)*(p_05_1_tr - length_1_tr));
					float S_2_tr = sqrt(p_05_2_tr*(p_05_2_tr - length_2)*(p_05_2_tr - length_1_tr)*(p_05_2_tr - length_3_tr));
					float S_3_tr = sqrt(p_05_3_tr*(p_05_3_tr - length_3)*(p_05_3_tr - length_3_tr)*(p_05_3_tr - length_2_tr));

					float sum = S_1_tr + S_2_tr + S_3_tr;
					if (FLOAT_EQ(S_Tr, sum))
					{
						choise.push_back(k);
						break;
					}
				}
				if ((*iter)->figure() == "Circle")
				{
					vector<double> coordCr = (*iter)->get_list_coordinates();
					if ((30)*(30) > (pt.x - coordCr.at(0))*(pt.x - coordCr.at(0)) + (pt.y - coordCr.at(1))*(pt.y - coordCr.at(1)))
					{
						choise.push_back(k);
						break;
					}
				}
				if ((*iter)->figure() == "Rectangle")
				{
					vector<double> coordRe = (*iter)->get_list_coordinates();

					float length_1_x = abs(coordRe.at(0) - pt.x);
					float length_2_x = abs(coordRe.at(2) - pt.x);
					float length_3_x = abs(coordRe.at(4) - pt.x);
					float length_4_x = abs(coordRe.at(6) - pt.x);

					float length_1_y = abs(coordRe.at(1) - pt.y);
					float length_2_y = abs(coordRe.at(3) - pt.y);
					float length_3_y = abs(coordRe.at(5) - pt.y);
					float length_4_y = abs(coordRe.at(7) - pt.y);

					float length_1_tr = sqrt(length_1_y*length_1_y + length_1_x*length_1_x);
					float length_2_tr = sqrt(length_2_x*length_2_x + length_2_y*length_2_y);
					float length_3_tr = sqrt(length_3_y*length_3_y + length_3_x*length_3_x);
					float length_4_tr = sqrt(length_4_y*length_4_y + length_4_x*length_4_x);

					float length_1_x_Re = abs(coordRe.at(0) - coordRe.at(2));
					float length_2_x_Re = abs(coordRe.at(0) - coordRe.at(4));
					float length_3_x_Re = abs(coordRe.at(2) - coordRe.at(6));
					float length_4_x_Re = abs(coordRe.at(4) - coordRe.at(6));

					float length_1_y_Re = abs(coordRe.at(1) - coordRe.at(3));
					float length_2_y_Re = abs(coordRe.at(1) - coordRe.at(5));
					float length_3_y_Re = abs(coordRe.at(3) - coordRe.at(7));
					float length_4_y_Re = abs(coordRe.at(5) - coordRe.at(7));

					float length_1 = sqrt(length_1_y_Re*length_1_y_Re + length_1_x_Re*length_1_x_Re);
					float length_2 = sqrt(length_2_x_Re*length_2_x_Re + length_2_y_Re*length_2_y_Re);
					float length_3 = sqrt(length_3_y_Re*length_3_y_Re + length_3_x_Re*length_3_x_Re);
					float length_4 = sqrt(length_4_y_Re*length_4_y_Re + length_4_x_Re*length_4_x_Re);

					float p_05_1_tr = (length_1 + length_2_tr + length_1_tr) / 2;
					float p_05_2_tr = (length_2 + length_1_tr + length_3_tr) / 2;
					float p_05_3_tr = (length_3 + length_4_tr + length_2_tr) / 2;
					float p_05_4_tr = (length_4 + length_4_tr + length_3_tr) / 2;

					float S_Re = length_1*length_2;
					float S_1_tr = sqrt(p_05_1_tr*(p_05_1_tr - length_1)*(p_05_1_tr - length_2_tr)*(p_05_1_tr - length_1_tr));
					float S_2_tr = sqrt(p_05_2_tr*(p_05_2_tr - length_2)*(p_05_2_tr - length_1_tr)*(p_05_2_tr - length_3_tr));
					float S_3_tr = sqrt(p_05_3_tr*(p_05_3_tr - length_3)*(p_05_3_tr - length_4_tr)*(p_05_3_tr - length_2_tr));
					float S_4_tr = sqrt(p_05_4_tr*(p_05_4_tr - length_4)*(p_05_4_tr - length_4_tr)*(p_05_4_tr - length_3_tr));

					float sum = S_1_tr + S_2_tr + S_3_tr + S_4_tr;

					if (FLOAT_EQ(S_Re, sum))
					{
						choise.push_back(k);
						break;
					}
				}
			}
			SendMessage(hWND, WM_PAINT, 0, 0);
			break;
		}
		POINT pt;

		GetCursorPos(&pt);

		ScreenToClient(hWND, &pt);

		pt.y = h - pt.y;

		vector<double> double_y;
		vector<double> double_x;
		double_x.push_back(pt.x);
		double_x.push_back(pt.x - 30);
		double_x.push_back(pt.x + 30);
		double_y.push_back(pt.y + 30);
		double_y.push_back(pt.y - 30);
		double_y.push_back(pt.y - 30);
		Figure *x_figure = new triangle(double_x, double_y);
		myfigure->push_back(x_figure);

		InvalidateRect(hWND, NULL, TRUE);
		break;
	}
	case WM_KEYDOWN:
	{
		switch (wParam)
		{
		case VK_ESCAPE:
		{
			choise.clear();
		}

		case VK_SHIFT:
		{
			POINT pt;

			GetCursorPos(&pt);

			ScreenToClient(hWND, &pt);
			pt.y = h - pt.y;
			auto figures = myfigure->getFigures();
			if (!choise.empty())
			{
				auto iter = figures.begin();
				Sleep(10);
					POINT pt2;
					GetCursorPos(&pt2);
					ScreenToClient(hWND, &pt2);
					pt2.y = h - pt2.y;
				for (int i = 0;i < choise.size();i++)
				{
					iter += choise[i];
					vector<double> coord = (*iter)->get_list_coordinates();
					
					if ((*iter)->figure() == "Triangle")
					{
						
						double xxx = pt.x-pt2.x ;
						double yyy = pt.y-pt2.y ;
						(*iter)->move(xxx, yyy);
					}
					if ((*iter)->figure() == "Circle")
					{
						double xxx = pt.x-pt2.x ;
						double yyy = pt.y-pt2.y ;
						(*iter)->move(xxx, yyy);
					}
					if ((*iter)->figure() == "Rectangle")
					{
						double xxx = pt.x-pt2.x ;
						double yyy = pt.y-pt2.y ;
						(*iter)->move(xxx, yyy);
					}
					iter -= choise[i];
				}
			}
			else
			{
				for (auto iter = figures.begin(); iter != figures.end(); iter++)
				{
					if ((*iter)->figure() == "Triangle")
					{
						vector<double> coordTr = (*iter)->get_list_coordinates();

						float length_1_x = abs(coordTr.at(0) - pt.x);
						float length_2_x = abs(coordTr[2] - pt.x);
						float length_3_x = abs(coordTr.at(4) - pt.x);

						float length_1_y = abs(coordTr.at(1) - pt.y);
						float length_2_y = abs(coordTr.at(3) - pt.y);
						float length_3_y = abs(coordTr.at(5) - pt.y);

						float length_1_tr = sqrt(length_1_y*length_1_y + length_1_x*length_1_x);
						float length_2_tr = sqrt(length_2_x*length_2_x + length_2_y*length_2_y);
						float length_3_tr = sqrt(length_3_y*length_3_y + length_3_x*length_3_x);

						float length_1_x_Tr = abs(coordTr.at(0) - coordTr.at(2));
						float length_2_x_Tr = abs(coordTr.at(0) - coordTr.at(4));
						float length_3_x_Tr = abs(coordTr.at(2) - coordTr.at(4));

						float length_1_y_Tr = abs(coordTr.at(1) - coordTr.at(3));
						float length_2_y_Tr = abs(coordTr.at(1) - coordTr.at(5));
						float length_3_y_Tr = abs(coordTr.at(3) - coordTr.at(5));

						float length_1 = sqrt(length_1_y_Tr*length_1_y_Tr + length_1_x_Tr*length_1_x_Tr);
						float length_2 = sqrt(length_2_x_Tr*length_2_x_Tr + length_2_y_Tr*length_2_y_Tr);
						float length_3 = sqrt(length_3_y_Tr*length_3_y_Tr + length_3_x_Tr*length_3_x_Tr);

						float p_05_1_Tr = (length_1 + length_2 + length_3) / 2;
						float p_05_1_tr = (length_1 + length_2_tr + length_1_tr) / 2;
						float p_05_2_tr = (length_2 + length_1_tr + length_3_tr) / 2;
						float p_05_3_tr = (length_3 + length_3_tr + length_2_tr) / 2;

						float S_Tr = sqrt(p_05_1_Tr*(p_05_1_Tr - length_1)*(p_05_1_Tr - length_2)*(p_05_1_Tr - length_3));
						float S_1_tr = sqrt(p_05_1_tr*(p_05_1_tr - length_1)*(p_05_1_tr - length_2_tr)*(p_05_1_tr - length_1_tr));
						float S_2_tr = sqrt(p_05_2_tr*(p_05_2_tr - length_2)*(p_05_2_tr - length_1_tr)*(p_05_2_tr - length_3_tr));
						float S_3_tr = sqrt(p_05_3_tr*(p_05_3_tr - length_3)*(p_05_3_tr - length_3_tr)*(p_05_3_tr - length_2_tr));

						float sum = S_1_tr + S_2_tr + S_3_tr;
						if (FLOAT_EQ(S_Tr, sum))
						{
							double xxx = pt.x - (coordTr.at(0)+ coordTr.at(2)+ coordTr.at(4))/3;
							double yyy = pt.y - (coordTr.at(5) + coordTr.at(1)+ coordTr.at(3))/3;
							(*iter)->move(xxx, yyy);
							break;
						}
					}
					if ((*iter)->figure() == "Circle")
					{
						vector<double> coordCr = (*iter)->get_list_coordinates();
						if ((30)*(30) > (pt.x - coordCr.at(0))*(pt.x - coordCr.at(0)) + (pt.y - coordCr.at(1))*(pt.y - coordCr.at(1)))
						{
							double xxx = pt.x - coordCr.at(0);
							double yyy = pt.y - (coordCr.at(1));
							(*iter)->move(xxx, yyy);
							break;
						}
					}
					if ((*iter)->figure() == "Rectangle")
					{
						vector<double> coordRe = (*iter)->get_list_coordinates();

						float length_1_x = abs(coordRe.at(0) - pt.x);
						float length_2_x = abs(coordRe.at(2) - pt.x);
						float length_3_x = abs(coordRe.at(4) - pt.x);
						float length_4_x = abs(coordRe.at(6) - pt.x);

						float length_1_y = abs(coordRe.at(1) - pt.y);
						float length_2_y = abs(coordRe.at(3) - pt.y);
						float length_3_y = abs(coordRe.at(5) - pt.y);
						float length_4_y = abs(coordRe.at(7) - pt.y);

						float length_1_tr = sqrt(length_1_y*length_1_y + length_1_x*length_1_x);
						float length_2_tr = sqrt(length_2_x*length_2_x + length_2_y*length_2_y);
						float length_3_tr = sqrt(length_3_y*length_3_y + length_3_x*length_3_x);
						float length_4_tr = sqrt(length_4_y*length_4_y + length_4_x*length_4_x);

						float length_1_x_Re = abs(coordRe.at(0) - coordRe.at(2));
						float length_2_x_Re = abs(coordRe.at(0) - coordRe.at(4));
						float length_3_x_Re = abs(coordRe.at(2) - coordRe.at(6));
						float length_4_x_Re = abs(coordRe.at(4) - coordRe.at(6));

						float length_1_y_Re = abs(coordRe.at(1) - coordRe.at(3));
						float length_2_y_Re = abs(coordRe.at(1) - coordRe.at(5));
						float length_3_y_Re = abs(coordRe.at(3) - coordRe.at(7));
						float length_4_y_Re = abs(coordRe.at(5) - coordRe.at(7));

						float length_1 = sqrt(length_1_y_Re*length_1_y_Re + length_1_x_Re*length_1_x_Re);
						float length_2 = sqrt(length_2_x_Re*length_2_x_Re + length_2_y_Re*length_2_y_Re);
						float length_3 = sqrt(length_3_y_Re*length_3_y_Re + length_3_x_Re*length_3_x_Re);
						float length_4 = sqrt(length_4_y_Re*length_4_y_Re + length_4_x_Re*length_4_x_Re);

						float p_05_1_tr = (length_1 + length_2_tr + length_1_tr) / 2;
						float p_05_2_tr = (length_2 + length_1_tr + length_3_tr) / 2;
						float p_05_3_tr = (length_3 + length_4_tr + length_2_tr) / 2;
						float p_05_4_tr = (length_4 + length_4_tr + length_3_tr) / 2;

						float S_Re = length_1*length_2;
						float S_1_tr = sqrt(p_05_1_tr*(p_05_1_tr - length_1)*(p_05_1_tr - length_2_tr)*(p_05_1_tr - length_1_tr));
						float S_2_tr = sqrt(p_05_2_tr*(p_05_2_tr - length_2)*(p_05_2_tr - length_1_tr)*(p_05_2_tr - length_3_tr));
						float S_3_tr = sqrt(p_05_3_tr*(p_05_3_tr - length_3)*(p_05_3_tr - length_4_tr)*(p_05_3_tr - length_2_tr));
						float S_4_tr = sqrt(p_05_4_tr*(p_05_4_tr - length_4)*(p_05_4_tr - length_4_tr)*(p_05_4_tr - length_3_tr));

						float sum = S_1_tr + S_2_tr + S_3_tr + S_4_tr;

						if (FLOAT_EQ(S_Re, sum))
						{
							double xxx = pt.x - (coordRe.at(0) + coordRe.at(2)+coordRe.at(4) + coordRe.at(6)) / 4;
							double yyy = pt.y - (coordRe.at(1) + coordRe.at(3)+ coordRe.at(5) + coordRe.at(7)) / 4;
							(*iter)->move(xxx, yyy);
							break;
						}
					}
				}
			}
			InvalidateRect(hWND, NULL, TRUE);
			break;
		}
		}

		break;
	}
	case WM_SIZE:
	{
		resize(LOWORD(lParam), HIWORD(lParam));

		break;
	}
	case WM_COMMAND:
	{
		int wmId = LOWORD(wParam);
		// Parse the menu selections:

		switch (wmId)
		{
		case IDM_ABOUT:
		{
			DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWND, About);
			break;
		}
		case ID_LOAD:
		{
			string text = { "result" };
			myfigure->load_file(text);
			SendMessage(hWND, WM_PAINT, 0, 0);
			break;
		}
		case ID_Save:
		{
			fstream clear("result.txt", ios::out);
			clear.close();
			myfigure->writeFile("result");
			//	myfigure->~Make_Figure();

			//	SendMessage(hWND, WM_PAINT, 0, 0);

			break;
		}
		case ID_Clear:
		{
			fstream clear("result.txt", ios::out);
			clear.close();
			break;
		}

		case IDM_EXIT:
			DestroyWindow(hWND);
			break;
		default:
			return DefWindowProc(hWND, message, wParam, lParam);
		}
	}
	break;
	case WM_PAINT:
	{
		hDC = BeginPaint(hWND, &ps);
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
		glEnable(GL_POINT_SMOOTH);
		glClearColor(0, 0, 0, 0);

		if (myfigure->getFigures().size() > 0)
		{
			int num = 0;
			for (auto i = myfigure->getFigures().begin(); i < myfigure->getFigures().end(); i++, num++)
			{
				if ((*i)->figure() == "Circle")
				{
					float r = 0.5, g = 0.7, b = 0.9;
					if (!choise.empty())
					{
						for (int i = 0;i < choise.size();i++)
						{
							if (choise[i] == num)
							{
								r = 1;g = 1;b = 1;
							}
						}
					}
					vector<double> data = (*i)->get_list_coordinates();

					glBegin(GL_POLYGON);
					glColor3f(r, g, b);
					for (int k = 0; k < data.size(); k += 2)
					{
						if (k > 900)
						{
							if (k == 902)
							{
								r -= 0.1;
								g -= 0.1;
								b -= 0.1;
							}
							glColor3f(r, g, b);
							glVertex2d(data.at(k), data.at(k + 1));
						}
						else if (k > 600)
						{
							if (k == 602)
							{
								r -= 0.1;
								g -= 0.1;
								b -= 0.1;
							}
							glColor3f(r, g, b);
							glVertex2d(data.at(k), data.at(k + 1));
						}
						else if (k > 300)
						{
							if (k == 302)
							{
								r -= 0.1;
								g -= 0.1;
								b -= 0.1;
							}
							glColor3f(r, g, b);
							glVertex2d(data.at(k), data.at(k + 1));
						}
						else
						{
							glVertex2d(data.at(k), data.at(k + 1));
						}
						//glColor3f(static_cast <float> (rand()) / static_cast <float> (RAND_MAX), static_cast <float> (rand()) / static_cast <float> (RAND_MAX), static_cast <float> (rand()) / static_cast <float> (RAND_MAX));

						//glColor3f(1, 0, 0.5);
					}
					glEnd();
				}
				else if ((*i)->figure() == "Triangle")
				{
					float r = 1, g = 0, b = 0;
					if (!choise.empty())
					{
						for (int i = 0;i < choise.size();i++)
						{
							if (choise[i] == num)
							{
								r = 1;g = 1;b = 1;
							}
						}
					}
					glColor3f(r, g, b);
					glBegin(GL_TRIANGLES);
					//glColor3f(static_cast <float> (rand()) / static_cast <float> (RAND_MAX), static_cast <float> (rand()) / static_cast <float> (RAND_MAX), static_cast <float> (rand()) / static_cast <float> (RAND_MAX));

					vector<double> data = (*i)->get_list_coordinates();
					glVertex2d(data.at(0), data.at(1));
					//glColor3f(static_cast <float> (rand()) / static_cast <float> (RAND_MAX), static_cast <float> (rand()) / static_cast <float> (RAND_MAX), static_cast <float> (rand()) / static_cast <float> (RAND_MAX));

					glVertex2d(data.at(2), data.at(3));
					//	glColor3f(static_cast <float> (rand()) / static_cast <float> (RAND_MAX), static_cast <float> (rand()) / static_cast <float> (RAND_MAX), static_cast <float> (rand()) / static_cast <float> (RAND_MAX));

					glVertex2d(data.at(4), data.at(5));
					glEnd();
				}
				else if ((*i)->figure() == "Rectangle")
				{
					glBegin(GL_TRIANGLE_STRIP);
					vector<double> data = (*i)->get_list_coordinates();
					float r = 1, g = 1, b = 0;
					if (!choise.empty())
					{
						for (int i = 0;i < choise.size();i++)
						{
							if (choise[i] == num)
							{
								r = 1;g = 1;b = 1;
							}
						}
					}
					glColor3f(r, g, b);
					glVertex2d(data.at(0), data.at(1));
					glVertex2d(data.at(2), data.at(3));
					glVertex2d(data.at(4), data.at(5));
					glVertex2d(data.at(6), data.at(7));
					glEnd();
				}
			}
		}

		SwapBuffers(hDC);
		EndPaint(hWND, &ps);
	}
	break;
	case WM_ERASEBKGND:
		return 1;
	case WM_DESTROY:
		KillTimer(hWND, 1);
		PostQuitMessage(0);
		break;
	default:
		return DefWindowProc(hWND, message, wParam, lParam);
	}
	return 0;
}

// Message handler for about box.
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
	UNREFERENCED_PARAMETER(lParam);
	switch (message)
	{
	case WM_INITDIALOG:
		return (INT_PTR)TRUE;

	case WM_COMMAND:
		if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
		{
			EndDialog(hDlg, LOWORD(wParam));
			return (INT_PTR)TRUE;
		}
		break;
	}
	return (INT_PTR)FALSE;
}